package com.wnxy.sddfp.trade.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.wnxy.sddfp.client.bank.TradeLogApi;
import com.wnxy.sddfp.client.system.UserApi;
import com.wnxy.sddfp.common.exception.BusinessException;
import com.wnxy.sddfp.common.model.dto.bid.AgencyBidDTO;
import com.wnxy.sddfp.common.model.dto.bid.BankBidDTO;
import com.wnxy.sddfp.common.model.dto.bid.BidBalanceDTO;
import com.wnxy.sddfp.common.model.vo.bid.AgencyBidVo;
import com.wnxy.sddfp.common.model.vo.user.TokenVo;
import com.wnxy.sddfp.common.model.vo.user.UserInfoVo;
import com.wnxy.sddfp.common.result.Result;
import com.wnxy.sddfp.common.result.enums.impl.BusinessCode;
import com.wnxy.sddfp.common.result.enums.impl.ResultCode;
import com.wnxy.sddfp.common.util.CalculateExpectUtil;
import com.wnxy.sddfp.common.util.TokenUtils;
import com.wnxy.sddfp.trade.entity.AgencyBid;
import com.wnxy.sddfp.trade.entity.BorrowRecord;
import com.wnxy.sddfp.trade.mapper.AgencyBidMapper;
import com.wnxy.sddfp.trade.mapper.BorrowRecordMapper;
import com.wnxy.sddfp.trade.service.IAgencyBidService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
 * <p>
 * 机构投标记录 服务实现类
 * </p>
 *
 * @author 作者
 * @since 2023-08-11
 */
@Service
public class AgencyBidServiceImpl extends ServiceImpl<AgencyBidMapper, AgencyBid> implements IAgencyBidService {
    @Autowired
    private UserApi userApi;
    @Autowired(required = false)
    private BorrowRecordMapper borrowRecordMapper;
    @Autowired
    private TradeLogApi tradeLogApi;

    @Override
    public AgencyBidVo addAgencyBidRecord(AgencyBidDTO agencyBidDTO) {
        // 第一：从token中获取登录用户信息
        TokenVo tokenVo = TokenUtils.getTokenVo();
        Result<UserInfoVo> resultUser = userApi.findById(Long.parseLong(tokenVo.getUserId()));
        UserInfoVo userInfoVo = resultUser.getData();
        String userCode = userInfoVo.getUserCode();

        // 第二：查询余额，判断机构认购用户的余额是否充足
        // 访问托管代理服务，获取账户余额;交易中心---》托管代理---》银行托管
        Result<BidBalanceDTO> resultBid = tradeLogApi.getBidBalance(userCode);
        BidBalanceDTO bidBalanceDTO = resultBid.getData();
        BigDecimal bidBalance = bidBalanceDTO.getBalance();
        // 投资金额与机构余额比较，判断账户是否充足
        BigDecimal amount = new BigDecimal(agencyBidDTO.getAmount());
        if (bidBalance.compareTo(amount) < 0) {
            throw new BusinessException(BusinessCode.BALANCE_NOT_ENOUGH);
        }

        BorrowRecord borrowRecord =
                borrowRecordMapper.selectById(agencyBidDTO.getBorrowRecordId());

        // 第三：保存投资认购记录
        AgencyBid agencyBid = this.saveAgencyBid(userInfoVo, borrowRecord, amount,tokenVo);

        // 第四：同步认购记录到银行托管。 交易中心-->代理-->托管
        // 调用托管代理，投资申购记录同步到银行托管系统，交易中心---》托管代理---》银行托管
        BankBidDTO bankBidDTO = BankBidDTO.builder()
                .amount(amount) //冻结金额
                .bizType("BID") //业务类型
                .borrowRecordNo(borrowRecord.getBorrowRecordNo())
                .reqCode(borrowRecord.getReqCode())     //请求流水号
                .userCode(userCode)   //投资机构用户编码
                .id(agencyBid.getId())  //业务实体标识
                .build();
        // 远程调用存管代理服务
        Result<String> resultBank =
                tradeLogApi.bankBidService(bankBidDTO);

        //根据结果更新投标状态
        if (resultBank.getCode() == ResultCode.SUCCESS.getCode()) {
            //3.2 修改状态为：已同步
            agencyBid.setStatus(1);
            this.updateById(agencyBid);
        }

        // 返回
        AgencyBidVo agencyBidVo = BeanUtil.copyProperties(agencyBid,AgencyBidVo.class);

        // 根据借款期限计算还款月数
        final Double ceil = Math.ceil(borrowRecord.getPeriod() / 30.0);
        Integer month = ceil.intValue();
        // 计算预期收益
        BigDecimal expected = CalculateExpectUtil.getIncomeTotalInterest(
                new BigDecimal(agencyBidDTO.getAmount()),
                new BigDecimal("0.5"), //TODO 年化收益
                month);
        agencyBidVo.setExpectedIncome(expected);
        return agencyBidVo;
    }

    // 保存机构认购记录
    private AgencyBid saveAgencyBid(UserInfoVo userInfoVo,BorrowRecord borrowRecord,
                                    BigDecimal amount,TokenVo tokenVo) {
        AgencyBid agencyBid = new AgencyBid();
        agencyBid.setUserId(Long.parseLong(tokenVo.getUserId()));
        agencyBid.setName(userInfoVo.getUserName());
        agencyBid.setUserCode(userInfoVo.getUserCode());
        agencyBid.setAmount(amount);
        agencyBid.setBidStatus("FROZEN");
        agencyBid.setCreateDate(LocalDateTime.now());
        agencyBid.setReqCode(borrowRecord.getReqCode());
        agencyBid.setStatus(0);
        agencyBid.setBorrowRecordId(borrowRecord.getId());
        agencyBid.setBorrowRecordNo(borrowRecord.getBorrowRecordNo());
        agencyBid.setBorrowRecordName(borrowRecord.getName());
        agencyBid.setBorrowRecordPeriod(borrowRecord.getPeriod());
        agencyBid.setInvestRate(borrowRecord.getInvestRate());
        this.save(agencyBid);
        return agencyBid;
    }
}
